package com.bto.solar.work.service;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bto.solar.work.constant.BizStageEnum;
import com.bto.solar.work.constant.BizTaskEnum;
import com.bto.solar.work.constant.BizTaskStateEnum;
import com.bto.solar.work.constant.Constants;
import com.bto.solar.work.constant.DBConstants;
import com.bto.solar.work.dao.ICompanyService;
import com.bto.solar.work.dao.ICustomerService;
import com.bto.solar.work.dao.IDeviceService;
import com.bto.solar.work.dao.IOrderBaseService;
import com.bto.solar.work.dao.IReconnoitreService;
import com.bto.solar.work.dto.CompanyCapacityStatRes;
import com.bto.solar.work.dto.order.QueryOrderReq;
import com.bto.solar.work.entity.Company;
import com.bto.solar.work.entity.Device;
import com.bto.solar.work.entity.OrderBase;
import com.bto.solar.work.entity.Reconnoitre;
import com.bto.solar.work.utils.NullUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author 王小波
 * @description:
 * @date 2023/9/7 10:41
 */
@Slf4j
@Service
public class BtoBiService {
    @Autowired
    private ICustomerService customerService;
    @Autowired
    private IDeviceService deviceService;
    @Autowired
    private IOrderBaseService orderBaseService;
    @Autowired
    private BtoOrderStateService btoOrderStateService;
    @Autowired
    private ICompanyService companyService;
    @Autowired
    private IReconnoitreService reconnoitreService;

    @Autowired
    private BtoUserService btoUserService;
    @Autowired
    private BtoOrderService btoOrderService;
    /**
     * 统计签约容量 不包括已经完工的
     * 技术勘察通过--初设评审未通过  都算签约
     * 技术勘察的 拟安装容量之和
     */
    public Integer statisticsSinged(Date startDate, Date endDate , QueryOrderReq orderReq) {
        //符合状态的
        Set<String> orderIds = getSingedStateOrderIds(startDate , endDate);
        if (NullUtils.isEmpty(orderIds)) {
            return 0;
        }
        //其他条件的
        List<OrderBase> orderBases =  orderBaseService.list(btoOrderService.buildOrderQueryWrapper(orderReq).in(OrderBase::getOrderId, orderIds));
        orderIds = orderBases.stream().map(OrderBase::getOrderId).collect(Collectors.toSet());

        if (NullUtils.isEmpty(orderIds)) {
            return 0;
        }

        List<Reconnoitre> reconnoitres = reconnoitreService.lambdaQuery()
                .select(Reconnoitre::getOrderId , Reconnoitre::getInstalledCapacityReckon)
                .in(Reconnoitre::getOrderId, orderIds)
                .list();
        if(NullUtils.isNull(reconnoitres)){
            return 0;
        }
        reconnoitres = reconnoitres.stream().filter(item -> NullUtils.isNotNull(item.getInstalledCapacityReckon())).collect(Collectors.toList());
        List<Integer> list = reconnoitres.stream().map(Reconnoitre::getInstalledCapacityReckon).collect(Collectors.toList());

        return list.stream().reduce(0, Integer::sum);
    }

    /**
    *  统计已经扫码的
     * 通过sto_device 表 sto_id 字段判断扫码 INST 前缀的
    */
    public Integer statisticsZuJianScanned(Date startDate, Date endDate , Long companyId) {
        Set<String> idsByStates = getZuJianScannedOrderIds(startDate, endDate);
        if(NullUtils.isEmpty(idsByStates)){
            return 0;
        }
        if(NullUtils.isNotNull(companyId) && NullUtils.isNotEmpty(idsByStates)){
            List<OrderBase> orderBases = orderBaseService.lambdaQuery()
                    .select(OrderBase::getOrderId)
                    .eq(OrderBase::getCompanyId, companyId)
                    .in(OrderBase::getOrderId , idsByStates).list();
            idsByStates = orderBases.stream().map(OrderBase::getOrderId).collect(Collectors.toSet());
        }

        if(NullUtils.isEmpty(idsByStates)){
            return 0;
        }

        List<Device> list = deviceService.lambdaQuery()
                .select(Device::getDeviceQuantity , Device::getModulePower)
                .eq(Device::getDeviceType, Constants.DEVICE_TYPE_ZUJIAN)
                .in(Device::getOrderId, idsByStates).list();


        Integer cap = 0 ;
        for (Device device : list){
            cap +=  device.getModulePower();
        }
        return cap;
    }


    /**
     *  统计建设中的容量
     *  设计审核通过后，施工信息待内审的容量
     */
    public Integer statisticsBuilding(Date startDate, Date endDate , QueryOrderReq orderReq) {
        //施工信息-待内审 均表示施工中
        BizStageEnum includeStage = BizStageEnum.CONSTRUCT;
        BizTaskEnum includeTask = BizTaskEnum.TASK_SGXX;
        List<BizTaskStateEnum> includeStates  = Arrays.asList(BizTaskStateEnum.WAITING_APPROVAL_BTO);

        Set<String> idsByStates = btoOrderStateService.getOrderIdsByStates(null, null, null,
                includeStage, includeTask, includeStates ,
                startDate , endDate);

        if(NullUtils.isEmpty(idsByStates)){
            return 0;
        }

        //其他条件的
        List<OrderBase> orderBases =  orderBaseService.list(btoOrderService.buildOrderQueryWrapper(orderReq)
                .in(OrderBase::getOrderId, idsByStates));
        idsByStates = orderBases.stream().map(OrderBase::getOrderId).collect(Collectors.toSet());

        if(NullUtils.isEmpty(idsByStates)){
            return 0;
        }



        List<Device> list = deviceService.lambdaQuery()
                .select(Device::getDeviceQuantity , Device::getModulePower)
                .eq(Device::getDeviceType, Constants.DEVICE_TYPE_ZUJIAN)
                .in(Device::getOrderId, idsByStates).list();


        Integer cap = 0 ;
        for (Device device : list){
            cap +=  device.getModulePower();
        }
        return cap;
    }

    /**
     *  统计等待建设的容量
     *  设计审核通过后，施工信息未填写
     */
    public Integer statisticsWaitingBuild(Date startDate, Date endDate) {
        //施工信息-待填写 表示等待施工
        BizStageEnum includeStage = BizStageEnum.CONSTRUCT;
        BizTaskEnum includeTask = BizTaskEnum.TASK_SGXX;
        List<BizTaskStateEnum> includeStates  = Arrays.asList(BizTaskStateEnum.WAITING_FILLED);

        Set<String> idsByStates = btoOrderStateService.getOrderIdsByStates(null, null, null,
                includeStage, includeTask, includeStates ,
                startDate , endDate);


        if(NullUtils.isEmpty(idsByStates)){
            return 0;
        }

        List<Device> list = deviceService.lambdaQuery()
                .select(Device::getDeviceQuantity , Device::getModulePower)
                .eq(Device::getDeviceType, Constants.DEVICE_TYPE_ZUJIAN)
                .in(Device::getOrderId, idsByStates).list();


        Integer cap = 0 ;
        for (Device device : list){
            cap += device.getModulePower();
        }
        return cap;
    }

    /**
     *  统计已并网容量
     *  完工容量及并网填写后
     */
    public Integer statisticsGridConnection(Date startDate, Date endDate ,QueryOrderReq orderReq) {
        //已完成、并网审核通过 -- 已并网容量
        BizStageEnum includeStage = BizStageEnum.GRID_CONNECTION;
        BizTaskEnum includeTask = BizTaskEnum.TASK_BWXX;
        List<BizTaskStateEnum> includeStates  = Arrays.asList(BizTaskStateEnum.APPROVAL_PASS_LEASE); //完成的单已经包含了该状态

        Set<String> idsByStates = btoOrderStateService.getOrderIdsByStates(null, null, null, false,
                includeStage, includeTask, includeStates,
                startDate, endDate);

        if (NullUtils.isEmpty(idsByStates)) {
            return 0;
        }
        List<OrderBase> orderBases = orderBaseService.list(btoOrderService.buildOrderQueryWrapper(orderReq).in(OrderBase::getOrderId, idsByStates));
        idsByStates = orderBases.stream().map(OrderBase::getOrderId).collect(Collectors.toSet());
        if (NullUtils.isEmpty(idsByStates)) {
            return 0;
        }

        List<Device> list = deviceService.lambdaQuery()
                .select(Device::getDeviceQuantity , Device::getModulePower)
                .eq(Device::getDeviceType, Constants.DEVICE_TYPE_ZUJIAN)
                .in(Device::getOrderId, idsByStates).list();


        Integer cap = 0 ;
        for (Device device : list){
            cap +=  device.getModulePower();
        }
        return cap;
    }

    /**
     *  公司容量统计
     */
    public List<CompanyCapacityStatRes> statisticsCompanyCapacity(Date startDate, Date endDate) {
        List<CompanyCapacityStatRes> resList = new ArrayList<>();

        List<Company> companies = companyService.lambdaQuery().in(Company::getType,
                DBConstants.COMPANY_TYPE_BRANCH_OFFICE,
                DBConstants.COMPANY_TYPE_PROJECT, DBConstants.COMPANY_TYPE_AGENT).list();

        companies.forEach(company ->{
            CompanyCapacityStatRes res = new CompanyCapacityStatRes();
            resList.add(res);
            Long companyId = company.getCompanyId();
            res.setCompanyId(company.getCompanyId());
            res.setCompanyName(company.getName());

            //查询公司签约容量
            Integer statisticsSinged = statisticsSinged(startDate, endDate, new QueryOrderReq().setCompanyId(companyId));
            res.setSignedCapacity(statisticsSinged);

            //查询公司扫码量
            Integer statisticsScanned= statisticsZuJianScanned(startDate, endDate, companyId);
            res.setScannedCapacity(statisticsScanned);

            //建设中
            Integer statisticsBuilding= statisticsBuilding(startDate, endDate,  new QueryOrderReq().setCompanyId(companyId));
            res.setBuildingCapacity(statisticsBuilding);

            //并网量
            Integer statisticsGridConnection= statisticsBuilding(startDate, endDate,  new QueryOrderReq().setCompanyId(companyId));
            res.setGridConnectionCapacity(statisticsGridConnection);

        });

        //默认按照并网排序
        return resList.stream().sorted(Comparator.comparing(CompanyCapacityStatRes::getSignedCapacity).reversed())
                .collect(Collectors.toList());
    }


    /**
    * 查询签约状态的订单
    */
    public Set<String> getSingedStateOrderIds(Date startDate, Date endDate){
        //未通过初设评审的
        BizStageEnum excludeStage = BizStageEnum.DESIGN;
        BizTaskEnum excludeTask = BizTaskEnum.TASK_CSPSXX;
        List<BizTaskStateEnum> excludeStates  = Arrays.asList(BizTaskStateEnum.APPROVAL_PASS_BTO, BizTaskStateEnum.APPROVAL_REJECT_BTO);
        //通过技术勘察的
        BizStageEnum includeStage = BizStageEnum.KAN_CHA;
        BizTaskEnum includeTask = BizTaskEnum.TASK_JSKC;
        List<BizTaskStateEnum> includeStates  = Arrays.asList(BizTaskStateEnum.APPROVAL_PASS_BTO);


        return btoOrderStateService.getOrderIdsByStates(excludeStage , excludeTask ,excludeStates , true,
                includeStage , includeTask , includeStates , startDate , endDate);
    }


    /**
     * 查询组件扫码状态的订单
     * 组件扫码：累加已完成的订单
     */
    public Set<String> getZuJianScannedOrderIds(Date startDate, Date endDate){
        //组件信息填写Ok的就算
        BizStageEnum includeStage = BizStageEnum.CONSTRUCT;
        BizTaskEnum includeTask = BizTaskEnum.TASK_SBXX_ZUJIAN;
        List<BizTaskStateEnum> includeStates  = Arrays.asList(BizTaskStateEnum.FILLED_OK);

        return btoOrderStateService.getOrderIdsByStates(null , null ,null ,
                includeStage , includeTask , includeStates , startDate , endDate);
    }


    /**
    * app 订单页面头部统计数据
    */
    public JSONObject appOrderPageHead(QueryOrderReq orderReq){
        if(NullUtils.isNull(orderReq)){
            orderReq = new QueryOrderReq();
        }
        JSONObject res = new JSONObject();

        LambdaQueryWrapper<OrderBase> orderBaseLambdaQueryWrapper = btoOrderService.buildOrderQueryWrapper(orderReq);
        long count = orderBaseService.count(orderBaseLambdaQueryWrapper);


        Integer statisticsSinged = statisticsSinged(null, null, orderReq);
        Integer statisticsBuilding = statisticsBuilding(null, null, orderReq);
        Integer statisticsGridConnection = statisticsGridConnection(null, null, orderReq);

        res.put("orderCount" , count);
        res.put("statisticsSinged" , statisticsSinged);
        res.put("statisticsBuilding" , statisticsBuilding);
        res.put("statisticsGridConnection" , statisticsGridConnection);


        return res;
    }


    /**
    *  对订单按照公司分分组
    */
    private Map<Long , List<String>> groupOrderByCompany(List<OrderBase> orderBaseList){
        Map<Long , List<String>> orderByCompany = new HashMap<>();
        orderBaseList.forEach( orderBase -> {
            List<String> list = orderByCompany.get(orderBase.getCompanyId());
            if(NullUtils.isNull(list)){
                list = new ArrayList<>();
                orderByCompany.put(orderBase.getCompanyId(),  new ArrayList<>());
            }
            list.add(orderBase.getOrderId());
        });
        return orderByCompany;
    }



}
